#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
数据库配置文件
支持多种数据库类型的配置
"""

import os
from typing import Dict, Any

class DatabaseConfig:
    """
    数据库配置类
    支持SQLite、PostgreSQL、MySQL等数据库
    """
    
    # 默认SQLite配置
    SQLITE_CONFIG = {
        'type': 'sqlite',
        'database': 'wechat_robot.db',
        'path': None  # 如果为None，将使用项目根目录
    }
    
    # PostgreSQL配置模板
    POSTGRESQL_CONFIG = {
        'type': 'postgresql',
        'host': 'localhost',
        'port': 5432,
        'database': 'wechat_robot',
        'username': 'postgres',
        'password': 'your_password',
        'options': {
            'sslmode': 'prefer',
            'connect_timeout': 10,
            'application_name': 'wechat_robot'
        }
    }
    
    # MySQL配置模板
    MYSQL_CONFIG = {
        'type': 'mysql',
        'host': 'localhost',
        'port': 3306,
        'database': 'wechat_robot',
        'username': 'root',
        'password': 'your_password',
        'options': {
            'charset': 'utf8mb4',
            'connect_timeout': 10
        }
    }
    
    @staticmethod
    def get_database_url(config: Dict[str, Any]) -> str:
        """
        根据配置生成数据库连接URL
        
        Args:
            config: 数据库配置字典
            
        Returns:
            str: 数据库连接URL
        """
        db_type = config.get('type', 'sqlite').lower()
        
        if db_type == 'sqlite':
            return DatabaseConfig._get_sqlite_url(config)
        elif db_type == 'postgresql':
            return DatabaseConfig._get_postgresql_url(config)
        elif db_type == 'mysql':
            return DatabaseConfig._get_mysql_url(config)
        else:
            raise ValueError(f"不支持的数据库类型: {db_type}")
    
    @staticmethod
    def _get_sqlite_url(config: Dict[str, Any]) -> str:
        """
        生成SQLite连接URL
        """
        database = config.get('database', 'wechat_robot.db')
        db_path = config.get('path')
        
        if db_path is None:
            # 使用项目根目录
            project_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
            db_path = os.path.join(project_root, database)
        else:
            db_path = os.path.join(db_path, database)
        
        return f'sqlite:///{db_path}'
    
    @staticmethod
    def _get_postgresql_url(config: Dict[str, Any]) -> str:
        """
        生成PostgreSQL连接URL
        """
        host = config.get('host', 'localhost')
        port = config.get('port', 5432)
        database = config.get('database', 'wechat_robot')
        username = config.get('username', 'postgres')
        password = config.get('password', '')
        
        # 构建基础URL
        url = f'postgresql://{username}:{password}@{host}:{port}/{database}'
        
        # 添加选项参数
        options = config.get('options', {})
        if options:
            params = '&'.join([f'{k}={v}' for k, v in options.items()])
            url += f'?{params}'
        
        return url
    
    @staticmethod
    def _get_mysql_url(config: Dict[str, Any]) -> str:
        """
        生成MySQL连接URL
        """
        host = config.get('host', 'localhost')
        port = config.get('port', 3306)
        database = config.get('database', 'wechat_robot')
        username = config.get('username', 'root')
        password = config.get('password', '')
        
        # 构建基础URL
        url = f'mysql+pymysql://{username}:{password}@{host}:{port}/{database}'
        
        # 添加选项参数
        options = config.get('options', {})
        if options:
            params = '&'.join([f'{k}={v}' for k, v in options.items()])
            url += f'?{params}'
        
        return url
    
    @staticmethod
    def load_config_from_env() -> Dict[str, Any]:
        """
        从环境变量加载数据库配置
        
        环境变量:
        - DB_TYPE: 数据库类型 (sqlite/postgresql/mysql)
        - DB_HOST: 数据库主机
        - DB_PORT: 数据库端口
        - DB_NAME: 数据库名称
        - DB_USER: 数据库用户名
        - DB_PASSWORD: 数据库密码
        
        Returns:
            Dict[str, Any]: 数据库配置
        """
        db_type = os.getenv('DB_TYPE', 'sqlite').lower()
        
        if db_type == 'sqlite':
            return {
                'type': 'sqlite',
                'database': os.getenv('DB_NAME', 'wechat_robot.db'),
                'path': os.getenv('DB_PATH')
            }
        elif db_type == 'postgresql':
            return {
                'type': 'postgresql',
                'host': os.getenv('DB_HOST', 'localhost'),
                'port': int(os.getenv('DB_PORT', '5432')),
                'database': os.getenv('DB_NAME', 'wechat_robot'),
                'username': os.getenv('DB_USER', 'postgres'),
                'password': os.getenv('DB_PASSWORD', ''),
                'options': {
                    'sslmode': os.getenv('DB_SSLMODE', 'prefer'),
                    'connect_timeout': int(os.getenv('DB_TIMEOUT', '10')),
                    'application_name': os.getenv('DB_APP_NAME', 'wechat_robot')
                }
            }
        elif db_type == 'mysql':
            return {
                'type': 'mysql',
                'host': os.getenv('DB_HOST', 'localhost'),
                'port': int(os.getenv('DB_PORT', '3306')),
                'database': os.getenv('DB_NAME', 'wechat_robot'),
                'username': os.getenv('DB_USER', 'root'),
                'password': os.getenv('DB_PASSWORD', ''),
                'options': {
                    'charset': os.getenv('DB_CHARSET', 'utf8mb4'),
                    'connect_timeout': int(os.getenv('DB_TIMEOUT', '10'))
                }
            }
        else:
            raise ValueError(f"不支持的数据库类型: {db_type}")
    
    @staticmethod
    def get_engine_options(db_type: str) -> Dict[str, Any]:
        """
        获取数据库引擎选项
        
        Args:
            db_type: 数据库类型
            
        Returns:
            Dict[str, Any]: 引擎选项
        """
        if db_type.lower() == 'sqlite':
            return {
                'pool_pre_ping': True,
                'pool_recycle': 300,
                'connect_args': {'check_same_thread': False}
            }
        elif db_type.lower() == 'postgresql':
            return {
                'pool_pre_ping': True,
                'pool_recycle': 3600,
                'pool_size': 10,
                'max_overflow': 20
            }
        elif db_type.lower() == 'mysql':
            return {
                'pool_pre_ping': True,
                'pool_recycle': 3600,
                'pool_size': 10,
                'max_overflow': 20,
                'connect_args': {'charset': 'utf8mb4'}
            }
        else:
            return {
                'pool_pre_ping': True,
                'pool_recycle': 300
            }